package minire;

import java.text.ParseException;
import java.util.Scanner;
import java.io.*;

/**
 * Main running class for the script reader and interpreter.
 */
public class MiniReMain {
	//
	// CLASS/INSTANCE DATA
	//
	/**
	 * The default grammar specification.
	 */
	public static final String MINIREGRAMMAR = "grammar.txt";
	
	/**
	 * The default output file.
	 */
	public static final String OUTPUTFILE = "outputLog.txt";
	
	public static void main(String[] args)
	{
		File outputFile = new File(OUTPUTFILE), grammar = new File("grammar.txt"), scriptFile = null;
		
		// 
		for(String arg : args)
		{
			String narg = arg.toLowerCase();
			String value = arg.split("=")[1];

			if(narg.startsWith("-i"))
			{
				scriptFile = new File(value);
			}
			else if(narg.startsWith("-o"))
			{
				outputFile = new File(value);
			}
			else if(narg.startsWith("-g"))
			{
				grammar = new File(value);
			}
		}
		
		// If we do not have the script, get it.
		Scanner input = new Scanner(System.in);
		if(scriptFile == null)
		{
			System.out.println("Please enter the name of the MiniRe script file: ");
			scriptFile = new File(input.nextLine());
		}
		
		// Load the minre script.
		FileInputStream fis = null;
		try
		{
			fis = new FileInputStream(scriptFile);
		}
		catch (FileNotFoundException ex)
		{
			System.out.println("An exception occured while attempting to access the script file.");
			System.out.println(ex.getMessage());
			System.out.println("Expected file at: " + scriptFile.getAbsolutePath());
			System.exit(0);
		}
		
		// Make sure the grammar specification is valid.
		Scanner grammarInput = null;
		try
		{
			grammarInput = new Scanner(grammar);
			RuleParser.parse(grammarInput);
			
		}
		catch (FileNotFoundException ex)
		{
			System.out.println("Grammar Specification Not Found");
			System.out.println("Please enter the grammar file location: ");
			try
			{
				grammarInput=new Scanner(new File(input.nextLine()));
			}
			catch(FileNotFoundException e2)
			{
				System.out.println("An exception occured while attempting to access the grammar specification.");
				System.out.println(ex.getMessage());
				System.out.println("Expected file at " + grammar.getAbsolutePath() + " or input location.");
				System.exit(0);
			}
		}
		finally
		{
			if(grammarInput != null)
				grammarInput.close();
		}
		
		// Create the output system for logging purposes.
		PrintWriter output = null;
		try
		{
			if(!outputFile.exists())
				outputFile.createNewFile();
			
			output = new PrintWriter(outputFile);
		}
		catch (FileNotFoundException ex)
		{			
			System.out.println("An exception occured while attempting to access the output file.");
			System.out.println(ex.getMessage());
			System.out.println("Expected file at: " + outputFile.getAbsolutePath());
			System.exit(0);
		}
		catch (IOException ex)
		{
			System.out.println("An exception occured while attempting to create the output file.");
			System.out.println(ex.getMessage());
			System.exit(0);
		}
		
		// Begin execution.
		try
		{
			// Generate the parser.
			output.println("Generating Parser From Grammar");
			Rule[] rules = RuleParser.rules.toArray(new Rule[0]);
			LL1Parser parse = ParserGenerator.generateParser(rules);
			output.println("Parser Generated");
			output.println("Finalize Parser:");
			output.println(parse);
			output.println();
			
			output.println("Parsing Script");
			AST<String> scriptSyn = parse.parse(fis);
			output.println("Completed Parsing Script");
			output.println("Final Syntax Tree:");
			output.println(scriptSyn.toString());
			output.println();
			
			output.println("Executing Script");
			MinReProgram script = new MinReProgram(scriptSyn);
			script.execute();
			output.println("Finished Executing Script");
		}
		catch (IOException ex)
		{
			System.out.println("An IOException occured while attempting to parse or run the script.");
			System.out.println(ex.getMessage());
			System.exit(0);
		}
		catch (ParseException ex)
		{
			System.out.println("A parsing error was encountered while trying to parse the script.");
			System.out.println(ex.getMessage());
			System.out.println("Error encountered at character offset: " + ex.getErrorOffset());
			System.exit(0);
		}
		finally
		{
			output.close();
			
			try
			{
				fis.close();
			}
			catch (IOException ex){}
		}
	}
}
